package core;

import static view.Constants.MAPPING;

public class Node implements Comparable<Node>
{

	/**
	 * the number of times the character has been repeated
	 */
	private int frequencies;

	/**
	 * The character mapped in byte
	 */
	private byte character;

	/**
	 * The left child of the node
	 */
	private Node left;

	/**
	 * The right child of the node
	 */
	private Node right;

	/**
	 * Creates an empty unconnected node 
	 */
	public Node() {}

	/**
	 * Creates a node with given character
	 * @param ch
	 */
	public Node(byte ch)
	{
		this(ch, 0);
	}

	/**
	 * Creates a node with given character and frequencies
	 * @param character the character of the node
	 * @param frequencies the number of frequencies the element has occurred
	 */
	public Node(byte character, int frequencies)
	{
		this(character, frequencies, null, null);
	}

	/**
	 * Creates fully connected full node data
	 * @param character the character of the node
	 * @param frequencies the number of frequencies the element has occurred 
	 * @param left the left child
	 * @param right the right child
	 */
	public Node(byte character, int frequencies, Node left, Node right)
	{
		this.frequencies = frequencies;
		this.character = character;
		this.left = left;
		this.right = right;
	}

	/**
	 * @return the frequency of the character
	 */
	public int getFrequencies()
	{
		return frequencies;
	}

	/**
	 * @return the character of the node
	 */
	public byte character()
	{
		return character;
	}

	/**
	 * @return the left child of the node
	 */
	public Node left()
	{
		return left;
	}

	/**
	 * sets the left child of the node
	 * @param left
	 */
	public void setLeft(Node left)
	{
		this.left = left;
	}

	/**
	 * @return the right child of the node
	 */
	public Node right()
	{
		return right;
	}

	/**
	 * sets the right child of the node
	 * @param right
	 */
	public void setRight(Node right)
	{
		this.right = right;
	}

	/**
	 * @return a string representation of the node
	 */
	public String toString()
	{
		return "Frequencies : " + frequencies + "\t character is : " + (char) (character + MAPPING);
	}

	/**
	 * compares two nodes and returns the difference
	 * @see Comparable#compareTo(Object)
	 */
	@Override
	public int compareTo(Node n)
	{
		return frequencies - n.frequencies;
	}

	/**
	 * @return true if the node is an external node
	 */
	public boolean isExternal()
	{
		return right == null && left == null;
	}

	/**
	 * @return true if the node has left child
	 */
	public boolean hasLeft()
	{
		return left != null;
	}

	/**
	 * @return true if the node has right child
	 */
	public boolean hasRight()
	{
		return right != null;
	}
}
